//=====================================================================
//
//=====================================================================
#ifndef PRISM_EMISSION_HPP
#define PRISM_EMISSION_HPP
//=====================================================================
#include <sooty/frontend/syntactic_analysis/parseme.hpp>
//=====================================================================
namespace prism {
//=====================================================================

	std::string decorated_type(sooty::const_parseme_ptr_ref);
	
	struct add_temporary_information_to_expressions
	{
		int& tmpvar;
		add_temporary_information_to_expressions(int& tmpvar) : tmpvar(tmpvar) {}
		void operator ()(sooty::parseme_ptr_ref);
	};
	
	namespace llvm
	{
		//=====================================================================
		// output stream
		//=====================================================================
		namespace detail {
			inline int& tabs() { static int _ = 0; return _; }
			inline std::ostream*& outstream() { static std::ostream* _; return _; }
		}
		
		inline std::ostream& output_stream(bool tabbed = true) {
			if (tabbed)
				for (int i = 0; i < detail::tabs(); ++i)
					(*detail::outstream()) << "\t";
			return *detail::outstream();
		}

		inline void add_tab() { ++detail::tabs(); }
		inline void sub_tab() { --detail::tabs(); }


		//=====================================================================
		// tree functions
		//=====================================================================
		void module(sooty::const_parseme_ptr_ref);
		void function(sooty::const_parseme_ptr_ref);
		void parameter_list(sooty::const_parseme_ptr_ref);
		void parameter(sooty::const_parseme_ptr_ref);
		void block(sooty::const_parseme_ptr_ref, const std::string&);
		void statement(sooty::const_parseme_ptr_ref);
		void argument(sooty::const_parseme_ptr_ref);
		void argument_list(sooty::const_parseme_ptr_ref);
		void access_expression(sooty::const_parseme_ptr_ref);
		void pre_mutate_expression(sooty::const_parseme_ptr_ref);
		void post_mutate_expression(sooty::const_parseme_ptr_ref);
		void phi_node( sooty::const_parseme_ptr_ref N, const std::string& block1, const std::string& block2 );
		
		//=====================================================================
		// functions that make sense for recursion
		//=====================================================================
		std::string rvalue_name(sooty::const_parseme_ptr_ref);
		std::string lvalue_name(sooty::const_parseme_ptr_ref);
		
		std::string storage_type_name(sooty::const_parseme_ptr_ref);
		std::string logical_type_name(sooty::const_parseme_ptr_ref);

		//std::string address_name(sooty::const_parseme_ptr_ref);
		//std::string deref_name(sooty::const_parseme_ptr_ref);
	}
	
//=====================================================================
} // namespace prism
//=====================================================================
#endif
//=====================================================================
